/*
ID: icerupt1
PROG: maze1
LANG: C++11
*/

/* solution
 *
 *
*/
#include <fstream>
#include <iostream>
#include <queue>

std::ifstream fin {"maze1.in" };
std::ofstream fout{"maze1.out"};

struct pos { int x, y; };

pos operator+(pos  a, pos b)
{
	a.x += b.x;  a.y += b.y;
	return a;
}

pos const opt[4] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int const maxn = 102;
bool vis[maxn][maxn];
int dis[maxn][maxn];
char da[2*maxn][2*maxn];
int w, h;

bool can_move(pos a, pos b)
{
	int ax = 2 * a.x + 1, ay = 2 * a.y + 1;
	int bx = 2 * b.x + 1, by = 2 * b.y + 1;
	ax = (ax + bx)/2;  ay = (ay + by)/2;
	return (da[ax][ay] == ' ');
}

bool inrange(pos a)
{
	return ((0 <= a.x && a.x < h) && (0 <= a.y && a.y < w));
}

int main()
{
	std::queue<pos> q;
	fin >> w >> h;
	char tchar;
	fin.get(tchar);
	for (int i = 0; i < 2 * h + 1; i++) {
		for (int j = 0; j < 2 * w + 1; j++) {
			fin.get(da[i][j]);
			if ((i == 0 || j == 0 || i == 2 * h || j == 2 * w)
					&& da[i][j] == ' ') {
				pos tmp;
				if (i == 0) { tmp.x = 0; tmp.y = (j-1)/2; };
				if (j == 0) { tmp.x = (i-1)/2; tmp.y = 0; };
				if (i == 2 * h) { tmp.x = h - 1; tmp.y = (j-1)/2; };
				if (j == 2 * w) { tmp.x = (i-1)/2; tmp.y = w - 1; };
				q.push(tmp);
				vis[tmp.x][tmp.y] = true;
			}
		}
		fin.get(tchar);
	}

	for (int i = 0; i < 2 * h + 1; i++) {
		for (int j = 0; j < 2 * w + 1; j++) std::cout << da[i][j];
		std::cout << '\n';
	}


	int ans = 0;
	while (!q.empty()) {
		pos tmp = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			pos ptmp = tmp + opt[i];
			if (inrange(ptmp) && !vis[ptmp.x][ptmp.y] && can_move(tmp, ptmp)) {
				q.push(ptmp);
				dis[ptmp.x][ptmp.y] = dis[tmp.x][tmp.y] + 1;
				ans = std::max(ans, dis[ptmp.x][ptmp.y]);
				vis[ptmp.x][ptmp.y] = true;
			}
		}
	}
	std::cout << ans + 1 << '\n';
	fout << ans + 1 << '\n';
}
